package com.cloud.security;

import com.cloud.common.configure.TransmittableHolder;
import com.cloud.common.constants.GlobalConstants;
import com.cloud.common.domain.Result;
import com.cloud.domain.LoginUser;
import com.cloud.entity.AuthBody;
import com.cloud.exception.CommonException;
import com.cloud.exception.LoginException;
import com.cloud.service.FeignSecurityService;
import com.cloud.utils.ServletUtils;
import jakarta.annotation.Resource;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.AsyncHandlerInterceptor;

import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
 * Security 权限认证拦过滤器
 *
 * @author yzj
 */
@Component
public class SecurityInterceptor implements AsyncHandlerInterceptor {

    @Resource
    private FeignSecurityService feignSecurityService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        try {
            String sysCode = request.getHeader(GlobalConstants.appTokenHeader);
            if (StringUtils.isEmpty(sysCode)) {
                return authRequestMessage(response, Result.message(LoginException.TOKEN_IS_EMPTY.getCode(),
                        LoginException.TOKEN_IS_EMPTY.getMsg()));
            }
            String tokenKey = ServletUtils.getHeader(request, GlobalConstants.tokenKey);
            TransmittableHolder.setTokenKey(tokenKey);
            // 根据Token获取当前用户认证信息
            AuthBody authBody = new AuthBody();
            authBody.setSysCode(sysCode);
            authBody.setTokenKey(tokenKey);
            LoginUser loginUser = feignSecurityService.getLoginUser(authBody).getData();
            if (ObjectUtils.isNotEmpty(loginUser)) {
                TransmittableHolder.setUserId(ServletUtils.getHeader(request, GlobalConstants.userId));
                TransmittableHolder.setUserName(ServletUtils.getHeader(request, GlobalConstants.userName));
                TransmittableHolder.setDeptId(ServletUtils.getHeader(request, GlobalConstants.deptId));
                loginUser.setSysCode(sysCode);
                TransmittableHolder.setLoginUser(loginUser);
            } else {
                return authRequestMessage(response, Result.message(LoginException.INVALID_TOKEN.getCode(),
                        LoginException.INVALID_TOKEN.getMsg()));
            }
        } catch (Exception e) {
            return authRequestMessage(response, Result.message(CommonException.SERVER_NO_EXITS.getCode(),
                    CommonException.SERVER_NO_EXITS.getMsg() + ",请先启动统一授权服务"));
        }
        return true;
    }

    /**
     * 所有拦截器的后置执行全部结束后,执行该操作
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        // 移除 TransmittableThreadLocal对象
        TransmittableHolder.remove();
    }

    private boolean authRequestMessage(HttpServletResponse response, Result result) {
        try {
            response.setContentType("application/json;charset=utf-8");
            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
            ServletOutputStream outputStream = response.getOutputStream();
            outputStream.write(result.toString().getBytes(StandardCharsets.UTF_8));
            // 关闭IO输出流
            outputStream.flush();
            outputStream.close();
        } catch (IOException e) {
            return false;
        }
        return false;
    }

}
